const transWorker = new Worker(new URL("./worker.js", import.meta.url)) // 音频实时播放
export class AudioPlayer {
  constructor({ stopCallBack } = {}) {
    this.mediaSource = null
    this.audio = null
    this.audioContext = null
    this.sourceBuffer = null
    this.pauseTimer = null
    this.stopCallBack = null
    this.cacheBuffers = []
    const AudioContext = window.AudioContext
    this.audioContext = new AudioContext()

    this.mediaSource = new MediaSource()

    this.audio = new Audio()
    // this.audio = audio
    this.audio.src = URL.createObjectURL(this.mediaSource)

    this.audioContextConnect()
    this.listenMedisSource()
    this.stopCallBack = stopCallBack
  }

  // 连接音频上下文
  audioContextConnect() {
    const source = this.audioContext.createMediaElementSource(this.audio)
    source.connect(this.audioContext.destination)
  }

  // 监听媒体资源
  listenMedisSource() {
    this.mediaSource.addEventListener("sourceopen", () => {
      if (this.sourceBuffer) {
        return
      }

      this.sourceBuffer = this.mediaSource.addSourceBuffer("audio/mpeg")

      this.sourceBuffer.addEventListener("update", () => {
        if (this.cacheBuffers.length && !this.sourceBuffer?.updating) {
          const cacheBuffer = this.cacheBuffers.shift()
          this.sourceBuffer?.appendBuffer(cacheBuffer)
        }

        this.pauseAudio()
      })
    })
  }

  // 暂停音频
  pauseAudio() {
    const neePlayTime = this.sourceBuffer.timestampOffset - this.audio.currentTime || 0

    this.pauseTimer && clearTimeout(this.pauseTimer)
    // 播放完成5秒后还没有新的音频流过来，则暂停音频播放
    this.pauseTimer = setTimeout(
      () => {
        this.audio.pause()
        this.stopCallBack()
        // console.log("播放完成")
      },
      neePlayTime * 1000 + 500
    )
  }

  pause() {
    try {
      this.audio.pause()
      this.cacheBuffers = []
      this.audio.currentTime = this.sourceBuffer.timestampOffset
    } catch (error) {}
  }

  playAudio() {
    // 为防止下一段音频流传输过来时，上一段音频已经播放完毕，造成音频卡顿现象，
    // 这里做了1秒的延时，可根据实际情况修正
    if (this.audio.paused) {
      try {
        this.audio.play()
      } catch (e) {
        this.playAudio()
      }
    }
  }

  // 接收音频数据
  receiveAudioData(audioData) {
    if (!audioData.byteLength) {
      return
    }

    if (this.sourceBuffer?.updating) {
      this.cacheBuffers.push(audioData)
    } else {
      this.sourceBuffer?.appendBuffer(audioData)
    }
  }

  play(audioData) {
    const beufferArr = this.transToAudioData(audioData)
    this.receiveAudioData(beufferArr)
    this.playAudio()
  }

  transToAudioData(audioDataStr) {
    const bytesBuffer = this.hexStringToByteArray(audioDataStr)
    const output = this.byteArrayToArrayBuffer(bytesBuffer)
    return output
  }

  byteArrayToArrayBuffer(byteArray) {
    const arrayBuffer = new ArrayBuffer(byteArray.length)
    const uint8Array = new Uint8Array(arrayBuffer)
    uint8Array.set(byteArray)
    return arrayBuffer
  }

  hexStringToByteArray(hexString) {
    hexString = atob(hexString)
    const outputArray = new Uint8Array(hexString.length)
    for (let i = 0; i < hexString.length; ++i) {
      outputArray[i] = hexString.charCodeAt(i)
    }
    return outputArray
  }
}

export default AudioPlayer
